import { record, pack, unpack } from 'rrweb'
import rrwebPlayer from 'rrweb-player'

class AzHawkEye {
  constructor() {
    this.lastEvents = []
    this.eventsList = []
    this.store = []
    this.player = null
    this.stopCB = null
    this.caches = null
  }

  get events() {
    return this.lastEvents.concat(this.eventsList)
  }

  run(options = {}) {
    this.lastEvents = []
    this.eventsList = []
    this.caches = null
    this.stopCB = record(
      Object.assign(
        {
          packFn: pack,
          checkoutEveryNms: 30000, // ms
        },
        options,
        {
          emit: (event, isCheckout) => {
            if (isCheckout) {
              this.lastEvents = this.eventsList
              this.eventsList = []
            }
            this.eventsList.push(event)
          },
        }
      )
    )
  }

  stop() {
    if (this.stopCB) {
      this.stopCB()
      this.caches = this.events
      this.stopCB = null
    }
  }

  save() {
    if (this.caches && this.caches.length && this.caches.length >= 2) {
      this.store.push(this.caches)
    }
    return this.store.length - 1
  }

  play({ el = document.body, events = this.caches || this.events, ...options } = {}) {
    if (events && events.length && events.length >= 2) {
      this.player && this.player.$destroy()
      this.player = new rrwebPlayer({
        target: el,
        props: Object.assign(
          {
            events,
            unpackFn: unpack,
            mouseTail: false,
            showWarning: false,
          },
          options
        ),
      })
      this.player.play()
    } else {
      throw new Error('AzHawkEye: Got nothing to play')
    }
  }

  playStore({ storeKey = this.store.length - 1, ...options } = {}) {
    if (!this.store.length) throw new Error('AzHawkEye: Got nothing to play')
    const events = this.store[storeKey]
    if (!events) throw new Error('AzHawkEye: Got an invalid storeKey')
    this.play({ ...options, events })
  }

  clearStore() {
    this.store = []
  }

  destroy() {
    this.player && this.player.$destroy()
    this.player = null
  }
}

export function createHawkEye() {
  return new AzHawkEye()
}
